#!/usr/bin/env python3
# -*- coding: utf-8; tab-width: 4; indent-tabs-mode: t -*-

# Copyright (c) 2019-2020 Fpemud <fpemud@sina.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated DocTemplation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import os
import subprocess
from dataclasses import dataclass
from .manpa_util import ManpaUtil


class ManpaDownloader:

    def __init__(self, parent):
        self._parent = parent
        self._parent._downloaderList.append(self)

        self._itemList = []

    def dispose(self):
        assert len(self._itemList) == 0
        if True:
            self._parent._downloaderList.remove(self)
            self._parent = None

    def is_downloading(self):
        return len(self._itemList) > 0

    def start_download(self, download_items):
        assert len(self._itemList) == 0

        if len(download_items) == 0:
            return

        for item in download_items:
            if isinstance(item, ManpaDownloadItemGeneralFile):
                assert len(download_items) == 1
            elif isinstance(item, ManpaDownloadItemGeneralDir):
                assert False
            elif isinstance(item, ManpaDownloadItemRsync):
                assert False
            elif isinstance(item, ManpaDownloadItemBittorrent):
                assert False
            elif isinstance(item, ManpaDownloadItemBaiduPan):
                assert False
            elif isinstance(item, ManpaDownloadItemAliYunPan):
                assert False
            else:
                assert False

        self._itemList = download_items

    def stop_download(self):
        # FIXME
        assert False

    def get_progress(self):
        ret = []
        for item in self._itemList:
            if isinstance(item, ManpaDownloadItemGeneralFile):
                # FIXME: should be async
                self._tmpDownloadWgetDownloadFile(item.url, item.local_file_path, False)
            elif isinstance(item, ManpaDownloadItemGeneralDir):
                assert False
            elif isinstance(item, ManpaDownloadItemRsync):
                assert False
            elif isinstance(item, ManpaDownloadItemBittorrent):
                assert False
            elif isinstance(item, ManpaDownloadItemBaiduPan):
                assert False
            elif isinstance(item, ManpaDownloadItemAliYunPan):
                assert False
            else:
                assert False

        # FIXME
        self._itemList = []
        return ret

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        self.dispose()

    def _tmpDownloadWgetDownloadFile(self, url, targetFullfn=None, using_tmpfile=False):
        assert not using_tmpfile

        if len(self._parent._proxyList) > 0:
            envDict = {
                'http_proxy': self._parent._proxyList[0],
                'https_proxy': self._parent._proxyList[0],
                'ftp_proxy': self._parent._proxyList[0],
            }
            envDict.update(os.environ)
        else:
            envDict = None

        if using_tmpfile:
            downloadingFullfn = os.path.join(os.path.dirname(targetFullfn), ".downloading")
        else:
            downloadingFullfn = targetFullfn

        # select User-Agent
        ua = ManpaUtil.getRandomUserAgent()

        ManpaUtil.forceDelete(downloadingFullfn)
        ManpaUtil.forceDelete(targetFullfn)

        cmdlist = ["wget", "-c"]
        if ua is not None:
            cmdlist += ["-U", ua]
        cmdlist += ["--quiet", "-O", downloadingFullfn, url]

        for i in ManpaUtil.sleepyZeroToMax(1, "long"):
            try:
                subprocess.check_call(cmdlist, env=envDict)
                break
            except subprocess.CalledProcessError:
                self._parent._warnCallback("Download file from \"%s\" failed for the %d time." % (url, i))

        if using_tmpfile:
            os.rename(downloadingFullfn, targetFullfn)


class ManpaDownloadItemGeneralFile:

    def __init__(self, **kwargs):
        assert "url" in kwargs
        self._url = kwargs["url"]
        assert self._url.startswith("http://") or self._url.startswith("https://") or self._url.startswith("ftp://")

        assert "local_file_path" in kwargs
        self._localFilePath = kwargs["local_file_path"]

    @property
    def url(self):
        return self._url

    @property
    def local_file_path(self):
        return self._localFilePath


class ManpaDownloadItemGeneralDir:
    pass


class ManpaDownloadItemRsync:
    pass


class ManpaDownloadItemBittorrent:
    pass


class ManpaDownloadItemBaiduPan:
    pass


class ManpaDownloadItemAliYunPan:
    pass


@dataclass
class ManpaDownloadProgress:
    status: int
